package metrics

import (
	"sync"

	"github.com/prometheus/client_golang/prometheus"
	"sigs.k8s.io/controller-runtime/pkg/metrics"
)

var MetricRegister = NewBKEClusterMetricRegister()

type BKEClusterMetricRegister struct {
	collectors map[string]Collector
	mux        sync.RWMutex
}

func NewBKEClusterMetricRegister() BKEClusterMetricRegister {
	return BKEClusterMetricRegister{
		collectors: make(map[string]Collector),
	}
}

func (r *BKEClusterMetricRegister) Register(key string) {
	r.mux.Lock()
	defer r.mux.Unlock()
	if r.collectors[key] != nil {
		return
	}
	r.collectors[key] = NewBKEClusterCollector(key)
	metrics.Registry.MustRegister(r.collectors[key])
}

func (r *BKEClusterMetricRegister) Unregister(key string) {
	r.mux.Lock()
	defer r.mux.Unlock()
	if r.collectors[key] == nil {
		return
	}
	metrics.Registry.Unregister(r.collectors[key])
	delete(r.collectors, key)
}

func (r *BKEClusterMetricRegister) Gather(key string, vecName ...string) (map[string][]map[string]string, error) {
	r.mux.RLock()
	collector, ok := r.collectors[key]
	r.mux.RUnlock()
	if !ok {
		return nil, nil
	}

	return collector.Export(vecName...)
}

func (r *BKEClusterMetricRegister) RecordGaugeVec(vecName, key string, lvs ...string) prometheus.Gauge {
	r.mux.RLock()
	defer r.mux.RUnlock()
	if collector, ok := r.collectors[key]; ok {
		return collector.RecordGaugeVecWithLabelValues(vecName, lvs...)
	}
	return nil
}

func (r *BKEClusterMetricRegister) RecordCounterVec(vecName, key string, lvs ...string) prometheus.Counter {
	r.mux.RLock()
	defer r.mux.RUnlock()
	if collector, ok := r.collectors[key]; ok {
		return collector.RecordCounterVecWithLabelValues(vecName, lvs...)
	}
	return nil
}
